package com.jianzh5.shiro;

import com.jianzh5.action.admin.AdminAction;
import com.jianzh5.entity.TAdmin;
import com.jianzh5.pojo.PResources;
import com.jianzh5.service.UserServiceI;
import com.jianzh5.util.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SystemAuthorizingRealm extends AuthorizingRealm{
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(SystemAuthorizingRealm.class);

	@Autowired
	private UserServiceI userService;
	
	/**
	 * 清空用户关联权限认证，待下次使用时重新加载
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
		clearCachedAuthorizationInfo(principals);
	}
	
	/**
	 * 清空所有关联认证
	 */
	public void clearAllCachedAuthorizationInfo() {
		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
		if (cache != null) {
			for (Object key : cache.keys()) {
				cache.remove(key);
			}
		}
	}
	
	
	/**
	 * 认证回调函数, 登录时调用
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken){
		UsernamePasswordCaptchaToken token =  (UsernamePasswordCaptchaToken) authcToken;
		if(AdminAction.isValidateCodeLogin(token.getUsername(), false, false)){
			logger.info("当前用户登录异常次数过多,需要输入验证码: 用户{"+token.getUsername()+"} Ip:{"+token.getHost()+"}");
			Session session = SecurityUtils.getSubject().getSession();
			String code = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
			if(token.getCaptcha() == null || !token.getCaptcha().equals(code) ){
				throw new CaptchaException("验证码错误.......");
			}
		}
		TAdmin admin = this.userService.getByAccount(token.getUsername());
		if(admin != null){
			return new SimpleAuthenticationInfo(new Principal(admin), admin.getPassword().toCharArray(), getName());
		}else{
			return null;
		}
	}
	
	/**
	 * 授权操作
	 */
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Principal pricipal = (Principal) getAvailablePrincipal(principals);
		TAdmin admin = this.userService.getByAccount(pricipal.getUsername());
		if(admin != null){
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
			List<PResources> resourcesList = UserUtils.getResourcesList();
			for(PResources res : resourcesList){
				if(StringUtils.isNotBlank(res.getPermission())){
					info.addStringPermission(res.getPermission());
				}
			}
			return info;
		}
		return null;
	}
	
	/**
	 * 授权用户信息
	 */
	public static class Principal implements Serializable {

		private static final long serialVersionUID = 1L;
		
		private int id;
		private String username;
		private String realname;
		private Map<String, Object> cacheMap;

		public Principal(TAdmin adminUser) {
			this.id = adminUser.getId();
			this.username = adminUser.getUsername();
			this.realname = adminUser.getRealname();
		}
		public int getId() {
			return id;
		}
		public String getUsername() {
			return username;
		}
		public String getRealname() {
			return realname;
		}

		public Map<String, Object> getCacheMap() {
			if (cacheMap==null){
				cacheMap = new HashMap<String, Object>();
			}
			return cacheMap;
		}
		@Override
		public String toString() {
			return "Principal [id=" + id + ", username=" + username
					+ ", realname=" + realname + "]";
		}
		
	}
	
}
